/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package pe.edu.pucp.sigepa.simulacion.nucleo;

import com.mysema.query.jpa.impl.JPAQuery;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.Persistence;
import pe.edu.pucp.sigepa.recocidosimulado.Modelo.Envio;
import pe.edu.pucp.sigepa.recocidosimulado.Modelo.EstadoItinerario;
import pe.edu.pucp.sigepa.recocidosimulado.Modelo.ItinerarioSim;
import pe.edu.pucp.sigepa.recocidosimulado.Modelo.PronosticoSim;
import pe.edu.pucp.sigepa.recocidosimulado.Modelo.QEnvio;
import pe.edu.pucp.sigepa.recocidosimulado.Modelo.TipoEscala;
import pe.edu.pucp.sigepa.recocidosimulado.Modelo.VueloSim;
import pe.edu.pucp.sigepa.recocidosimulado.domain.interfaz.ProblemaSim;
import pe.edu.pucp.sigepa.recocidosimulado.domain.interfaz.SolucionSim;
import pe.edu.pucp.sigepa.recocidosimulado.fachada.MotorGeneradorTrayectoriasFachadaSimulacion;
import pe.edu.pucp.sigepa.simulacion.interfaz.AmpliacionAeropuerto;
import pe.edu.pucp.sigepa.simulacion.interfaz.AmpliacionVuelo;
import pe.edu.pucp.sigepa.simulacion.interfaz.EntradaNucleoSimulador;

/**
 *
 * @author carloslengua
 */
public class NucleoSimulador {

    public void iniciarSimulacion(EntradaNucleoSimulador entradaNucleoSimulador) throws ParseException {
//        throw new UnsupportedOperationException("Not supported yet.");
        volcarDatos();

        aplicarNecesidades(entradaNucleoSimulador);

        correrEscenarioSimulado();

    }

    private void volcarDatos() {

        //Depuracion
        System.out.println("Iniciando volcado de datos...");

        EntityManager em = Persistence.createEntityManagerFactory("pe.edu.pucp_motor-generador-rutas-RS2_jar_1.0-SNAPSHOTPU", System.getProperties())
                .createEntityManager();

        em.getTransaction().begin();

        List listaResultado = em.createNativeQuery("select volcado_simulacion()").getResultList();

        System.out.println("listaResultado = " + listaResultado);

        em.getTransaction().commit();

        //Depuracion
        System.out.println("Volcado de datos exitoso...");

    }

    private void aplicarNecesidades(EntradaNucleoSimulador entradaNucleoSimulador) {
//        throw new UnsupportedOperationException("Not supported yet.");
        
        //Depuracion
        System.out.println("Iniciando aplicacion de necesidades...");        

        List<AmpliacionAeropuerto> ampliacionesAeropuertos = entradaNucleoSimulador.getAmpliacionesAeropuertos();
        List<AmpliacionVuelo> ampliacionesVuelos = entradaNucleoSimulador.getAmpliacionesVuelos();
        
        EntityManager em = Persistence.createEntityManagerFactory("pe.edu.pucp_motor-generador-rutas-RS2_jar_1.0-SNAPSHOTPU", System.getProperties())
                                .createEntityManager();
        
        em.getTransaction().begin();
       
//        Integer resultadoActualizacion;
        
        for (AmpliacionAeropuerto ampliacionAeropuerto : ampliacionesAeropuertos) {
            
            em.createNativeQuery("UPDATE aeropuerto_sim SET capPack = ?1 WHERE idAeropuerto = ?2")
                    .setParameter(2, ampliacionAeropuerto.getAeropuertoId())
                    .setParameter(1, ampliacionAeropuerto.getCapacidadFinal())
                    .executeUpdate();
            
        }
        
        for (AmpliacionVuelo ampliacionVuelo : ampliacionesVuelos) {
            
            em.createNativeQuery("update avion_sim set idtipo = ?1 where idavion in (select distinct idavion from vuelo_sim vs where vs.idorigen = ?2 and vs.iddestino = ?3)")
                    .setParameter(2, ampliacionVuelo.getAeropuertoOrigenId())
                    .setParameter(3, ampliacionVuelo.getAeropuertoDestinoId())
                    .setParameter(1, ampliacionVuelo.getTipoAvionFinalId())
                    .executeUpdate();            
            
        }        
        
        em.getTransaction().commit();    
        
        //Depuracion
        System.out.println("Aplicacion de necesidades exitosa...");             

    }

    private void correrEscenarioSimulado() throws ParseException {
//        throw new UnsupportedOperationException("Not yet implemented");
        
        //Depuracion        
        System.out.println("Iniciando ejecucion de escenario simulado...");        

        JPAQuery consulta = new JPAQuery(
                Persistence.createEntityManagerFactory("pe.edu.pucp_motor-generador-rutas-RS2_jar_1.0-SNAPSHOTPU", System.getProperties())
                .createEntityManager());

        QEnvio envio = QEnvio.envio;

//        List<Envio> envios = consulta.from(envio)
//                                .where(envio.fechareg.after(new SimpleDateFormat("yyyy-MM-dd").parse("2012-09-02"))
//                                        .and(envio.fechareg.before(new SimpleDateFormat("yyyy-MM-dd").parse("2012-09-04")))).list(envio);
        
        List<Envio> envios = consulta.from(envio)
                                .where(envio.idenvio.eq(7).or(envio.idenvio.eq(8)).or(envio.idenvio.eq(9))).list(envio);        

        ProblemaSim problemaSim;
        SolucionSim solucionSim;

        MotorGeneradorTrayectoriasFachadaSimulacion motorGeneradorTrayectoriasFachadaSimulacion = new MotorGeneradorTrayectoriasFachadaSimulacion();

        for (Envio envioActual : envios) {
            
            //Depuracion        
            System.out.println("Atendiendo envio " + envioActual + "...");                

//            problemaSim = new ProblemaSim(envioActual.getFechareg(), envioActual.getUsuario().getAeropuerto().getIdaeropuerto(), envioActual.getAeropuerto().getIdaeropuerto(), envioActual.getNumpack());
            problemaSim = new ProblemaSim(new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").parse("2012-09-02 08:00:00"), envioActual.getUsuario().getAeropuerto().getIdaeropuerto(), envioActual.getAeropuerto().getIdaeropuerto(), envioActual.getNumpack());

            solucionSim = motorGeneradorTrayectoriasFachadaSimulacion.obtenerSolucion(problemaSim);
            
            //Depuracion        
            System.out.println("SolucionSim = " + solucionSim);                
            
            if (solucionSim != null) {
                generarItinerarioSimulado(envioActual, solucionSim);
            }

        }
        
        //Depuracion        
        System.out.println("Ejecucion de escenario simulado exitoso...");             
        
    }

    private void generarItinerarioSimulado(Envio envio, SolucionSim lstVuelos) {
        
        JPAQuery consulta = null;       

        ItinerarioSim itinerarioSim = new ItinerarioSim();
        EstadoItinerario estado = new EstadoItinerario();
        TipoEscala tipo = new TipoEscala();
        itinerarioSim.setEnvio(envio);
        itinerarioSim.setEstadoItinerario(estado);
        int escala = 1;
        for (int i = 0; i < lstVuelos.size(); i++) {
            if (escala == 1) {
                tipo.setIdtipo(1);//1 inicio
                estado.setIdestado(1);//1 Pendiente
            } else if (escala == lstVuelos.size()) {
                tipo.setIdtipo(3);//3 fin
                estado.setIdestado(4);//4 En Espera
            } else {
                tipo.setIdtipo(2);//2 paso
                estado.setIdestado(4);//4 En Espera
            }
            itinerarioSim.setTipoEscala(tipo);
            itinerarioSim.setSeq(escala);

            // Crear constructor copia
//            VueloSim vueloSim = new VueloSim(lstVuelos.get(i));
            
//            consulta = new JPAQuery(
//                    Persistence.createEntityManagerFactory("pe.edu.pucp_motor-generador-rutas-RS2_jar_1.0-SNAPSHOTPU", System.getProperties())
//                    .createEntityManager()); 
//            
//            QVueloSim vueloSim = QVueloSim.vueloSim;
//            
//            Integer idVueloSim = lstVuelos.get(i).getIdvuelo();
//            VueloSim vueloSimulado = consulta.from(vueloSim).where(vueloSim.idvuelo.eq(idVueloSim)).uniqueResult(vueloSim);
            
            VueloSim vueloSimulado = lstVuelos.get(i);
            
            itinerarioSim.setEstadoItinerario(estado);
            itinerarioSim.setVueloSim(vueloSimulado);

            insertarItinerarioSim(itinerarioSim);

            //Actualiza tabla pronostico
            actualizarPronosticoSim(vueloSimulado, envio.getNumpack());

            //Actualiza escala
            escala++;
        }

    }

    private void insertarItinerarioSim(ItinerarioSim itinerarioSim) {
//        Session session = HibernateUtil.getSessionFactory().openSession();
//        Transaction tx =  session.beginTransaction();
//        session.save(iter);
//        tx.commit();
//        session.close();  

        EntityManager em = Persistence.createEntityManagerFactory("pe.edu.pucp_motor-generador-rutas-RS2_jar_1.0-SNAPSHOTPU", System.getProperties())
                .createEntityManager();
        
        em.getTransaction().begin();
        
        em.persist(itinerarioSim);
        
        em.getTransaction().commit();
    }

    private void actualizarPronosticoSim(VueloSim v, int numPack) {
//        //Abrir sesión
//        Session session = HibernateUtil.getSessionFactory().openSession();
//        Transaction tx =  session.beginTransaction();     

        EntityManager em = Persistence.createEntityManagerFactory("pe.edu.pucp_motor-generador-rutas-RS2_jar_1.0-SNAPSHOTPU", System.getProperties())
                .createEntityManager();

        em.getTransaction().begin();

        //Prepara pronostico
        PronosticoSim pronosticoSimEntrada = new PronosticoSim();
        
        pronosticoSimEntrada.setAeropuertoSim(v.getAeropuertoSimOrigen()); //AeropuertoOrigen
//        pronosticoSimEntrada.setAeropuertoSim(null); //AeropuertoOrigen        
        pronosticoSimEntrada.setFechareg(v.getSalidaest()); //salidaEstimada
        pronosticoSimEntrada.setNropack((-1) * numPack);

        PronosticoSim pronosticoSimSalida = new PronosticoSim();
        pronosticoSimSalida.setAeropuertoSim(v.getAeropuertoSimDestino()); //AeropuertoDestino
//        pronosticoSimSalida.setAeropuertoSim(null); //AeropuertoDestino        
        pronosticoSimSalida.setFechareg(v.getLlegadaest()); //salidaEstimada
        pronosticoSimSalida.setNropack(numPack);

        //Ejecutar inserts
//        session.save(pronosticoSimEntrada);
//        session.save(pronosticoSimSalida);
        em.persist(pronosticoSimEntrada);
        em.persist(pronosticoSimSalida);


        //Confirmar transacción y cerrar sesión
        em.getTransaction().commit();
//        tx.commit();
//        session.close();
    }

}
